#ifndef FABRICARECURSOS_H_
#define FABRICARECURSOS_H_

#include "RecursoAlmacenamiento.h"
#include "Singleton.h"
#include "includes.h"

namespace Toolkit
{

class FabricaRecursos: public Singleton<FabricaRecursos>
{
public:

    RecursoAlmacenamiento *recursoBuffer(
            const UnidadAlmacenamiento &uAlmacenamiento,
            const unsigned long int &tamanoUnidad);

    RecursoAlmacenamiento *recursoArchivo(const string &rutaArchivo,
            const string &nombreArchivo,
            const UnidadAlmacenamiento &uAlmacenamiento,
            const unsigned long int &tamanoUnidad,
            const TipoIndexado &tIndexado);

    RecursoAlmacenamiento *recursoEscrituraDirecta(const string &rutaArchivo,
            const string &nombreArchivo,
            const UnidadAlmacenamiento &uAlmacenamiento,
            const unsigned long int &tamanoUnidad,
            const TipoIndexado &tIndexado);

    RecursoAlmacenamiento *recursoEscrituraDiferida(const string &rutaArchivo,
                const string &nombreArchivo,
                const UnidadAlmacenamiento &uAlmacenamiento,
                const unsigned long int &tamanoUnidad,
                const TipoIndexado &tIndexado,
			const unsigned long int &catidadElementosBuffer);

    RecursoAlmacenamiento *recuperarRecurso(const string &rutaArchivo,
            const string &nombreArchivo, const TipoSerializacion &tSerializacion);

private:

    EstrategiaAlmacenamiento *getEstrategiaAlmacenamiento(
            const UnidadAlmacenamiento &uAlmacenamiento,
            const unsigned long int &tamanoBloque);

    Indice *getIndice(const TipoIndexado &tIndexado, const UnidadAlmacenamiento &uAlmacenamiento,
            const unsigned long int &tamanoUnidad, const TipoSerializacion &tSerializacion,
            const string &ruta, const string &nombre, const bool &nuevo = true);

    void generarMetadata(const TipoSerializacion &tSerializacion,
            const UnidadAlmacenamiento &uAlmacenamiento,
            const TipoIndexado &tIndexado, const EstrategiaBuffering &buffering,
            stringstream &metadata, const unsigned long int &elementosBuffer);

    void leerMetadata(const TipoSerializacion &tSerializacion,
            stringstream &metadata, UnidadAlmacenamiento &uAlmacenamiento,
            TipoIndexado &tIndexado, EstrategiaBuffering &buffering,
            unsigned long int &elementosBuffer);
};

}

#endif /*FABRICARECURSOS_H_*/
